`timescale 1ns / 1ps


module compare_branch#(parameter D_WIDTH=34, OPCODE_WIDTH = 5)
(
	input isBranch_i,
	input [OPCODE_WIDTH-1:0] control,
	input [D_WIDTH-1:0] r1_i,
	input [D_WIDTH-1:0] r2_i,
	output branch_true_o,
	output return_true_o,
	output call_true_o
);

////////////////////////////////////////////////////////////////////////
// local param

	localparam BA 	= 5'd16;
	localparam BE	= 5'd17;
	localparam BNE	= 5'd18;
	localparam BG	= 5'd19;
	localparam BGE	= 5'd20;
	localparam BL	= 5'd21;
	localparam BLE	= 5'd22;
	localparam CALL	= 5'd27;
	localparam RETURN = 5'd31;

////////////////////////////////////////////////////////////////////////
// reg & assign 

	reg branch_true_r;
	assign branch_true_o = branch_true_r;
	
	reg return_true_r;
	assign return_true_o = return_true_r;
	
	reg call_true_r;
	assign call_true_o = call_true_r;
	
////////////////////////////////////////////////////////////////////////

always_comb
begin
	if(isBranch_i)
	begin
	
		branch_true_r = 1'b0;
		return_true_r = 1'b0;
		call_true_r = 1'b0;
		
		case(control)
		
		BA: 
			begin
			branch_true_r = 1'b1;
			end
			
		BE: 
			begin
			if(r1_i == r2_i)
				branch_true_r = 1'b1;
			end
			
		BNE:
			begin
			if(r1_i != r2_i)
				branch_true_r = 1'b1;
			end
			
		BG: 
			begin
			if(r1_i > r2_i)
				branch_true_r = 1'b1;
			end
			
		BGE:
			begin
			if(r1_i >= r2_i)
				branch_true_r = 1'b1;
			end
			
		BL:
			begin
			if(r1_i < r2_i)
				branch_true_r = 1'b1;
			end
			
		BLE:
			begin
			if(r1_i <= r2_i)
				branch_true_r = 1'b1;
			end
		
		CALL:
		begin
			call_true_r = 1'b1;
		end
		
		RETURN:
		begin
			return_true_r = 1'b1;
		end
		
		default: // unused opcode: 23 to 32
			begin
			branch_true_r = 1'b0;
			return_true_r = 1'b0;
			call_true_r = 1'b0;
			end
				
		endcase
	end 
	else 
	begin	
		branch_true_r = 1'b0;
		return_true_r = 1'b0;
		call_true_r = 1'b0;
	end
end

////////////////////////////////////////////////////////////////////////

endmodule

